



/* plugin definition*/
(function($){
	$.fn.jsizzlebox = function(options) {
	
		var defaults = {
			autofilter: true,
			onSubmit: function(){}
		}; 
	
	
		var options = $.extend(defaults, options); 
		
		this.each(function() {  
			var obj = $(this);
			
			init();/* initialize the list and build the html markup*/
			
			/*Common objects */
			var toggle = $(obj).children(".jsizzlebox_input_wrapper").children(".jsizzlebox_toggle");
			var input_wrapper = $(obj).children(".jsizzlebox_input_wrapper");
			var list_wrapper = $(obj).children(".jsizzlebox_list_wrapper");
			var ul = $(obj).children(".jsizzlebox_list_wrapper").children("ul.jsizzle_list");
			var input = $(obj).children(".jsizzlebox_input_wrapper").children(".jsizzlebox_input");
			var li = $(obj).children(".jsizzlebox_list_wrapper").children("ul.jsizzle_list").children('li');
			var ac= options.autofilter;
			var listHeight = $(list_wrapper).css("height").split("px")[0];
			var listBorderBottomStyle = $(list_wrapper).css("border-bottom-style");
			var listBorderBottomColor = $(list_wrapper).css("border-bottom-color");
			var listBorderBottomWidth = $(list_wrapper).css("border-bottom-width");
			
			$(ul).children("li:last").css("border-bottom","none");/*this needed to be set to none because of the border control issues*/
			
			/******************************************* Events *****************************************/
			
			/*Changes the background on hover event*/
			
			$(toggle).hover(
				function () {
					$(input_wrapper).addClass("jsizzlebox_input_wrapper_hover");
				}, 
				function () {
					$(input_wrapper).removeClass("jsizzlebox_input_wrapper_hover");
				}
			);
			
			/*Event for when the arrow toggle button is clicked*/
			$(toggle).click(function () { 
				$(list_wrapper).toggle();
				
				/*Reset the bottom border */
				$(list_wrapper).css("border-bottom",listBorderBottomStyle+" "+listBorderBottomColor+" "+listBorderBottomWidth);
				
				/*resets the list elements to default state*/
				resetListElements();
				$(input).focus();
				
				
				/*if the list is not dropped down set the focus to the input*/
				if($(list_wrapper).css("display") == "none")
				{
					$(input).focus();
				}
				$(this).blur();/* removes dotted outline in IE*/
			});
			
			
			
			
			
			/*On hover of list elements toggle the focused class*/
			$(li).hover(
				function () {
					$(this).addClass("focused");
				}, 
				function () {
					$(this).removeClass("focused");
				}	
			);
			
			/*On click of list element*/
			$(li).click(function () { 
	
				var selected = $(this).children("a").html();
	  
				$(input).val(selected);
	  
				$(list_wrapper).toggle();
	  
				$(input).focus();
	  
				/*resets the list elements to default state*/
				resetListElements();
	  
				selected = null;
				
				options.onSubmit.call(this);
			});
			
			/*key down event on input*/
			$(input).keydown(function (e) {
				var key = e.which;
				/*38 up*/
				/*40 down*/
		
				if(key == 40)/*if down arrow*/
				{
					navDown();
				}
					else if(key == 38) /*if up arrow*/
				{
	   
					navUp();
			
				}
	   
				else if(key == 13)/*if enter*/
				{
					var selected = $(ul).children("li.focused").children("a").html();
			
					if(selected == null)
					{
						options.onSubmit.call(this);
						
					}
			
					if($(list_wrapper).css("display") == "block")
					{

						if(selected != null)
						{
							$(input).val(selected);
						}
						$(list_wrapper).toggle();
				
						/*resets the list elements to default state*/
						resetListElements();
					}
					
					if(selected != null)
					{
					
						options.onSubmit.call(this);
						
					}
				}
	   
	   
				key = null;
	   
	   
			});/* End keydown event */
			
			$(input).keyup(function (e) {
		
				if(e.which != 40 && e.which != 38 && e.which != 13)
				{
					
					if(ac)/*checking for autocomplete on or off*/
					{
						if(filter())
						{
						
						
							$(list_wrapper).css("display","block");
							
							var ulHeight = parseFloat($(ul).css("height").split("px")[0]);

							if(ulHeight <= listHeight)
							{
								$(list_wrapper).css("border-bottom","none");
							}
							else
							{
								$(list_wrapper).css("border-bottom",listBorderBottomStyle+" "+listBorderBottomColor+" "+listBorderBottomWidth);
							}
							
						}
						else
						{
							$(list_wrapper).css("display","none");
							$(list_wrapper).css("border-bottom",listBorderBottomStyle+" "+listBorderBottomColor+" "+listBorderBottomWidth);
							resetListElements();
						}
					}
				}
		
			});
			
			
			/*********************** Functions Used **********************************/
			function init()
			{
			
				/* first we're going to retrieve all of the link elements in our list*/
				var listAry = $(obj).children("ul").children("li").children("a");
				
				/* now we're going to start buildingnt the html structure.  The classes you see here are styled in the jsizzlebox.css*/
				/* 
				
					The final structure will look something like this
					<div id="myComboBox1">
						<div class="jsizzlebox_input_wrapper">
							<input class="jsizzlebox_input" type="text"/><a href="#jsizzlebox_toggle" class="jsizzlebox_toggle"><span class="hide" style="">open</span></a>
						</div>
						<div class="jsizzlebox_list_wrapper">
							<ul class="jsizzle_list">
								<li tabindex = "1"><a href="#">aab</a></li>
								<li tabindex = "2"><a href="#">aac</a></li>
								<li tabindex = "3"><a href="#">acc</a></li>
								<li tabindex = "4"><a href="#">ccb</a></li>
								<li tabindex = "5"><a href="#">ccd</a></li>
								<li tabindex = "6"><a href="#">caa</a></li>
								<li tabindex = "7"><a href="#">ddb</a></li>
							<li tabindex = "8"><a href="#">ccz</a></li>
							</ul>
						</div>
					</div>
				*/
				
				
				
				$(obj).empty();
				$(obj).append("<div class='jsizzlebox_input_wrapper'><input class='jsizzlebox_input' type='text'/><a href='#jsizzlebox_toggle' class='jsizzlebox_toggle'><span class='hide'>open</span></a></div>");
				$(obj).append("<div class='jsizzlebox_list_wrapper'></div>");
				
				$(obj).children(".jsizzlebox_list_wrapper").append("<ul class='jsizzle_list'></ul>");
				
				/* Retrive the UL tag that we just appended to the main object*/
				var initUl = $(obj).children(".jsizzlebox_list_wrapper").children(".jsizzle_list");
				
				
				/*
					here I'm rebuilding the list in the structure that works with this script
					if you wish to use something other then link elements inside your li elements like a span or img or whatever
					make sure you change the below append statement to reflect your changes.
					Also you would want to search through the plugin code and find any place that is referenceing .children("a").html()
					and replace that with your new element to get the value that the user is selecting. 
				
				*/
				
				$(listAry).each(function (i) {
					$(initUl).append("<li tabindex="+(i+1)+"><a href="+$(this).attr('href')+" class="+$(this).attr('class')+" id="+$(this).attr('id')+">"+$(this).html()+"</a></li>");
				});
				
				
				list = null;
				initUl = null;
			};
			
			/* Resets the list elements to their default state*/
			function resetListElements(){
				$(ul).children("li").each(function(){
					$(this).css("display","block");
					$(this).css("visibility","visible");
		
					if($(this).hasClass("focused"))
					{
						$(this).removeClass("focused");
					}
				});
			};/*end function resetListElements*/
			
			/*Filters the list on the values provided in the input field*/
			function filter()
			{
				var inputStr = $(input).val().toLowerCase();;
				var inputStrSize = inputStr.length;
				var cnt = 0;
				var returnVal = false;
			
				resetListElements();
			
				if(inputStrSize > 0)
				{
				
					$(ul).children("li").each(function(){
						var elStr = $(this).children("a").html().toLowerCase();;
						var elSize = elStr.length;
						var compare = elStr.substring(0,inputStrSize);
				
						if(inputStr != compare)
						{
							$(this).css("display","none");
							$(this).css("visibility","hidden");
						}
						else
						{
							cnt++;
						}
						
						
					
						elStr = null;
						elSize = null;
						compare = null;
				
					});
					
				
					if(cnt == 0)
					{
						resetListElements();
						returnVal = false;
					}
					else
					{
						returnVal = true;
					}
				}
				else
				{
					returnVal = false;
					resetListElements();
				}
			
			
				inputStr = null;
				inputStrSize = null;
				cnt = null;
	
				return returnVal;
	
			};/*end function filter*/
			
			/* controls the focus on the arrow button up */
			function navUp()
			{
				if(ac)
				{
					var objAry = $(ul).children("li:visible");
					
					if(objAry.size() == 0 && $(input).val().length == 0)
					{
						resetListElements();
						$(list_wrapper).css("display","block");
					}
					
					if($(ul).children("li:first").hasClass("focused"))
						{
							$(list_wrapper).toggle();
					
					
					
							/*resets the list elements to default state*/
							resetListElements();
						}
	
					if(objAry.size() > 0)
					{
		
						var firstTabIndex = $(objAry[0]).attr("tabindex");
						var lastTabIndex = $(objAry[(objAry.size() - 1)]).attr("tabindex");
						var currentObj = $(ul).children("li:visible.focused");
		
						if(currentObj.size() == 0)
						{
							$(ul).children("li[tabindex='"+lastTabIndex+"']").addClass("focused");
							$(list_wrapper).scrollTo( $(ul).children("li.focused"), 5 );
						}
						else
						{
							var nextPos;
							$(objAry).each(function (i) {
								if($(this).attr("tabindex") == $(currentObj).attr("tabindex"))
								{
									$(this).removeClass("focused");
									nextPos = i-1;
								}
							});
							
							
							
							$(objAry[nextPos]).addClass("focused");
							
							var scrollIndex = (nextPos - 2);
							$(list_wrapper).scrollTo( $(ul).children("li[tabindex="+scrollIndex+"]"), 5 );
							
							scrollIndex = null;
							nextPos =null;
						}
		
					}
				}
				
				else
				{
					if($(list_wrapper).css("display") == "none")
					{
						$(list_wrapper).toggle();
						$(ul).children("li:last").addClass("focused");
						$(list_wrapper).scrollTo( $(ul).children("li:last"), 5 );
					}
					else 
					{
			
						if($(ul).children("li:first").hasClass("focused"))
						{
							$(list_wrapper).toggle();
					
					
					
							/*resets the list elements to default state*/
							resetListElements();
						}
						else
						{
			
							var currentIndex = $(ul).children("li.focused").attr("tabindex");
							var nextIndex = currentIndex - 1;
				
				
							/*remove the focused class from the last element*/
							$(ul).children("li.focused").removeClass("focused");
							$(ul).children("li[tabindex='"+nextIndex+"']").addClass("focused");
							
							
							var scrollIndex = (nextIndex - 2);
							$(list_wrapper).scrollTo( $(ul).children("li[tabindex="+scrollIndex+"]"), 5 );
					
							currentIndex = null;
							nextIndex = null;
							scrollIndex = null;
						}
					}
				}
				
				

			};/*End Function Nav Up*/
			
			/* controls the focus on the arrow button down*/
			function navDown()
			{
				
				if(ac)
				{
					var objAry = $(ul).children("li:visible");
				
					if(objAry.size() == 0 && $(input).val().length == 0)
					{
						resetListElements();
						$(list_wrapper).css("display","block");
					}
	
					if(objAry.size() > 0)
					{
		
						var firstTabIndex = $(objAry[0]).attr("tabindex");
						var lastTabIndex = $(objAry[(objAry.size() - 1)]).attr("tabindex");
						var currentObj = $(ul).children("li:visible.focused");
		
						if(currentObj.size() == 0)
						{
			
							$(ul).children("li[tabindex='"+firstTabIndex+"']").addClass("focused");
							$(list_wrapper).scrollTo( $(ul).children("li.focused"), 5 );
			
						}
						else
						{
							var nextPos;
							$(objAry).each(function (i) {
								if($(this).attr("tabindex") == $(currentObj).attr("tabindex"))
								{
									$(this).removeClass("focused");
									nextPos = i+1;
								}
							});
			
							$(objAry[nextPos]).addClass("focused");
							
							
							
							var scrollIndex = (nextPos - 2);
							$(list_wrapper).scrollTo( $(ul).children("li[tabindex="+scrollIndex+"]"), 5 );
							
							
							
							/** forces the focus to stop on the last available list element **/
							
					
							
							if($(ul).children("li.focused").size() == 0)
							{
								nextPos = nextPos - 1;
						
								$(objAry[nextPos]).addClass("focused");
							}
							
							scrollIndex = null
							nextPos = null;
						}
		
					}
				}
				else
				{
					if($(list_wrapper).css("display") == "none")
					{
						$(list_wrapper).toggle();
						$(ul).children("li:first").addClass("focused");
						$(list_wrapper).scrollTo( $(ul).children("li:first"), 5 );
					}
					else 
					{
						if($(ul).children("li:last").hasClass("focused"))
						{
						
							/*
								if you want the list to close after the last element looses focus add these lines
							
								$(list_wrapper).toggle();
								resetListElements();
							*/
							
							
						}
						else
						{
							var currentIndex = $(ul).children("li.focused").attr("tabindex");
							var nextIndex = currentIndex - 1 + 2;
				
				
							/*remove the focused class from the last element*/
							$(ul).children("li.focused").removeClass("focused");
							
							$(ul).children("li[tabindex='"+nextIndex+"']").addClass("focused");
							
							var scrollIndex = (nextIndex - 2);
							
							$(list_wrapper).scrollTo( $(ul).children("li[tabindex="+scrollIndex+"]"), 5 );
				
							currentIndex = null;
							nextIndex = null;
							scrollIndex = null;
						}
						
	
					}
					
					
				}
	
			};/*end function navDown*/
			
			
		});/*End each function*/
		
	}; /*end function jsizzlebox*/
	
	
})(jQuery);  